package com.dubbo.common.redis.impl;

import com.alibaba.fastjson.JSON;
import com.dubbo.common.SerializeUtil;
import com.dubbo.common.redis.RedisService;
import com.dubbo.common.redis.tool.RedisFunction;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.Set;


/**
 * 单机版实现类
 */
public class JedisPoolServiceImpl implements RedisService {
	/** 注入JedisPool连接池对象 */
	@Resource
	private JedisPool jedisPool;
	
	/** 定义执行的方法 */
	private <T> T execute(RedisFunction<T> redisFunction){
		Jedis jedis = null;
		try{
			jedis = jedisPool.getResource();
			return redisFunction.callback(jedis);
		}finally{
			jedis.close();
		}
	}
	
	/**
	 * 设置键对应的值
	 * @param key 键
	 * @param value 值
	 * @return 状态码
	 */
	public String set(final String key,final String value){
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis) {
				return jedis.set(key, value);
			}
		});
	}
	/**
	 * 设置键对应的值 (生存时间)
	 * @param key 键
	 * @param value 值
	 * @param seconds 秒数
	 * @return 状态码
	 */
	public String setex(final String key, final String value,final int seconds){
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis) {
				return jedis.setex(key, seconds, value);
			}
		});
	}
	/**
	 * 通过键获取指定的值
	 * @param key 键
	 * @return 值
	 */
	public String get(final String key){
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis){
				return jedis.get(key);
			}
		});
	}
	

	
	/**
	 * 根据键删除指定的值
	 * @param key 键
	 * @return 状态码
	 */
	public Long del(final String key){
		return execute(new RedisFunction<Long>() {
			@Override
			public Long callback(Jedis jedis) {
				return jedis.del(key);
			}
		});
	}
	/**
	 * 设置键的生存时间
	 * @param key 键
	 * @param seconds 秒
	 * @return 状态码 
	 */
	public Long expire(final String key,final int seconds){
		return execute(new RedisFunction<Long>() {
			@Override
			public Long callback(Jedis jedis) {
				return jedis.expire(key, seconds);
			}
		});
	}
	/**
	 * 获取一个键自增长的值
	 * @param key 键
	 * @return 自增长的值
	 */
	public Long incr(final String key){
		return execute(new RedisFunction<Long>() {
			@Override
			public Long callback(Jedis jedis) {
				return jedis.incr(key);
			}
		});
	}
	
	/**
	 * 删除当前选定数据库的所有键
	 */
	@Override
	public String delAll() {
		// TODO Auto-generated method stub
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis) {
				return jedis.flushDB();
			}
		});
	}
	/**
	 * 返回当前选定数据库中的键数量
	 */
	@Override
	public Long dbSize() {
		// TODO Auto-generated method stub
		return execute(new RedisFunction<Long>() {
			@Override
			public Long callback(Jedis jedis) {
				return jedis.dbSize();
			}
		});
	}
	
	/**
	 * 根据键名模糊查询所有key
	 */
	@Override
	public Set<String> keys(final String pattern) {
		// TODO Auto-generated method stub
		return execute(new RedisFunction<Set<String>>() {
			@Override
			public Set<String> callback(Jedis jedis) {
				return jedis.keys(pattern);
			}
		});
	}
	/**
	 * 根据key获取字节数组
	 */
	@Override
	public byte[] getByte(final String key) {
		// TODO Auto-generated method stub
		return execute(new RedisFunction<byte[]>() {
			@Override
			public byte[] callback(Jedis jedis) {
				byte[] serialize = null;
				try {
					serialize = SerializeUtil.serialize(key);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return jedis.get(serialize);
			}
		});
	}
	
	/**
	 * 设置键对应的序列化值
	 * @throws Exception 
	 */
	@Override
	public String set(final String key,final byte[] value) throws Exception {
		final byte[] serialize = SerializeUtil.serialize(key);
		// TODO Auto-generated method stub
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis) {
				
				return jedis.set(serialize,value);
			}
		});
	}
	/**
	 * 设置键对应的序列化值,和数据的生命周期
	 * @return 
	 * @throws Exception 
	 */
	@Override
	public String setex(final String key, final byte[] value,final int timeout) throws Exception {
		// TODO Auto-generated method stub
		final byte[] serialize = SerializeUtil.serialize(key);
		return execute(new RedisFunction<String>() {
			@Override
			public String callback(Jedis jedis) {
				return jedis.setex(serialize, timeout, value);
			}
		});
	}
	/**
	 * 通过键获取指定的值
	 */
	@SuppressWarnings("all")
	@Override
	public <T> T get(final String key,final Class clazz) {
		return execute(new RedisFunction<T>() {
			@Override
			public T callback(Jedis jedis) {
				try {
					byte[] serializeKey = SerializeUtil.serialize(key);
					byte[] value = jedis.get(serializeKey);
					String valueStr = (String) SerializeUtil.deserialize(value);
					return (T) JSON.parseObject(valueStr,clazz);
				} catch (Exception e) {
					return null;
				}
			}
		});
	}
}